package com.bestcem.xm.survey.export.type;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.bestcem.xm.survey.export.BaseTypeHandler;
import com.bestcem.xm.survey.grpc.client.dto.QstructsDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

import static com.bestcem.xm.survey.enums.QuestionTypeEnum.QUESTION_TYPE_SINGLE;

@Slf4j
@Component
public class SingleHandler implements BaseTypeHandler {


    @Override
    public Map<String, String> getSelectColumnChangeDictV2(JSONObject data, String dtype) {
        Map<String, String> column_change_dict = new HashMap(2);
        //选项选项
        column_change_dict.put(getSelectRealcolV2(data), getSelectReadablecolV2(data));
        return column_change_dict;
    }

    private String getSelectRealcolV2(JSONObject data) {
        //cid:题目可见编号
        return data.getString("cid");
    }

    private String getSelectReadablecolV2(JSONObject data) {
        return BaseTypeHandler.clearHtml(data.getString("title"));
    }

    @Override
    public Map<String, String> getOpenColumnChangeDictV2(JSONObject data) {
        Map<String, String> res = new HashMap();
        List<JSONObject> items = (List<JSONObject>) data.getOrDefault("items", Collections.emptyList());
        items.forEach(v -> {
            if (isOpenRow(v)) {
                res.put(getOpenRealcolV2(data, v), getOpenReadablecolV2(data, v));
            }
        });
        return res;
    }

    private String getOpenReadablecolV2(JSONObject data, JSONObject item) {
        return String.format("%s__%s__开放", BaseTypeHandler.clearHtml(data.getString("title")), BaseTypeHandler.clearHtml(item.getString("title")));
    }

    private String getOpenRealcolV2(JSONObject data, JSONObject item) {
        return String.format("%s__%s__open", data.getString("cid"), item.getString("oid"));
    }

    @Override
    public Map<String, String> getScoreColumnChangeDictV2(JSONObject data, QstructsDto qStruct) {
        Map<String, String> res = new HashMap();
        JSONObject scores = JSONObject.parseObject(qStruct.getScores());
        if (!scores.isEmpty() && scores.containsKey(data.getString("gid"))) {
            res.put(getScoreRealcolV2(data), getScoreReadablecolV2(data));
        }
        return res;
    }

    private String getScoreRealcolV2(JSONObject data) {
        return String.format("%s__score", data.getString("cid"));
    }

    private String getScoreReadablecolV2(JSONObject data) {
        return String.format("%s__评分", BaseTypeHandler.clearHtml(data.getString("title")));
    }

    @Override
    public List<String> getSelectColumnListV2(JSONObject data, String dtype) {
        return Arrays.asList(getSelectRealcolV2(data));
    }

    @Override
    public List<String> getOpenColumnListV2(JSONObject data) {
        List<String> res = new ArrayList();
        List<JSONObject> items = (List<JSONObject>) data.getOrDefault("items", Collections.emptyList());
        items.forEach(s -> {
            if (isOpenOption(s)) {
                res.add(getOpenRealcolV2(data, s));
            }
        });
        return res;
    }

    @Override
    public List<String> getScoreColumnListV2(JSONObject data, QstructsDto qStruct) {
        List<String> res = new ArrayList();
        JSONObject scores = JSONObject.parseObject(qStruct.getScores());
        if (!scores.isEmpty() && scores.containsKey(data.getString("gid"))) {
            res.add(getScoreRealcolV2(data));
        }
        return res;
    }

    @Override
    public Map<String, Map<Object, Object>> getConvertTableV2(JSONObject q) {
        Map<String, Map<Object, Object>> table = new HashMap();
        List<JSONObject> items = (List<JSONObject>) q.get("items");
        items.forEach(item -> {
            String value = getSelectRealcolV2(q);
            table.compute(value, (k, s) -> {
                if (Objects.isNull(s)) {
                    s = new HashMap<>(2);
                }
                s.put(item.getInteger("gid"), BaseTypeHandler.clearHtml((String) item.get("title")));
                return s;
            });
        });
        return table;
    }

    @Override
    public Map<Object, Object> getSelectAnswerDictV2(JSONObject dataValue, Object answers, String dtype, Boolean score_apply_type) {
        Map<Object, Object> data = new HashMap<>();
        List<JSONObject> items = (List<JSONObject>) dataValue.getOrDefault("items", Collections.emptyList());
        if (Objects.isNull(answers)) {
            //np.nan 可以理解为null
            items.forEach(v -> data.put(getSelectRealcolV2(dataValue), null));
        } else {
            if (ObjectUtil.isNotEmpty(answers)) {
                if (answers instanceof List) {
                    if ("readable".equals(dtype)) {
                        data.put(getSelectRealcolV2(dataValue), ((List) answers).get(0));
                    } else {
                        List<JSONObject> option_list = (List<JSONObject>) dataValue.getOrDefault("option_list", Collections.emptyList());
                        Map<Integer, String> gid_oid_dict = new HashMap<>();
                        option_list.forEach(v -> gid_oid_dict.put(v.getInteger("gid"), v.getString("oid")));
                        //np.nan 可以理解为null
                        data.put(getSelectRealcolV2(dataValue), gid_oid_dict.get(((List) answers).get(0)));
                    }
                } else {
                    data.put(getSelectRealcolV2(dataValue), answers);
                }
            } else {
                data.put(getSelectRealcolV2(dataValue), null);
            }
        }
        return data;
    }


    @Override
    public Map<Object, Object> getOpenAnswerDictV2(JSONObject dataValue, Object answer) {
        Map<Object, Object> data = new HashMap<>();
        List<JSONObject> items = (List<JSONObject>) dataValue.getOrDefault("items", Collections.emptyList());
        if (Objects.isNull(answer)) {
            items.forEach(item -> {
                if (isOpenOption(item)) {
                    data.put(getOpenRealcolV2(dataValue, item), null);
                }
            });
        } else {
            items.forEach(item -> {
                if (isOpenOption(item)) {
                    if (answer instanceof List && (item.getInteger("gid").equals(((List) answer).get(0))) && ((List) answer).size() > 1) {
                        data.put(getOpenRealcolV2(dataValue, item), BaseTypeHandler.clearHtml((String) ((List) answer).get(1)));
                    } else {
                        data.put(getOpenRealcolV2(dataValue, item), null);
                    }
                }
            });
        }
        return data;
    }

    @Override
    public Map<Object, Object> getScoreAnswerDictV2(JSONObject dataValue, Object answers, QstructsDto qstructsDto, JSONObject score_dict, String dtype) {
        Map<Object, Object> data = new HashMap<>();
        if (Objects.nonNull(qstructsDto) && StrUtil.isNotEmpty(qstructsDto.getScores())
                && JSONObject.parseObject(qstructsDto.getScores()).containsKey(dataValue.getString("gid"))) {
            //np.nan 可以理解为null
            data.put(getScoreRealcolV2(dataValue), null);
        }
        if (Objects.nonNull(answers)) {
            Float score = 0f;
            try {
                String key = String.format("%s_%s", dataValue.getString("gid"), ((List) answers).get(0));
                if (CollUtil.isNotEmpty(score_dict) && score_dict.containsKey(key)) {
                    Float tmp_score = score_dict.getFloat(key);
                    if (Objects.nonNull(tmp_score)) {
                        score = Float.valueOf(tmp_score);
                    }
                    score = Float.parseFloat(String.format("%.2f", score));
                }
            } catch (Exception e) {
                log.error("分数转换异常：{}", e);
                //np.nan 可以理解为null
                score = null;
            }
            data.put(getScoreRealcolV2(dataValue), score);
        }
        return data;
    }

    @Override
    public List<List<String>> getVarLabelsV2(JSONObject dataValue, boolean not01, boolean need_title) {
        List<List<String>> data = new ArrayList<>();
        List<String> var_list = new ArrayList(), val_list = new ArrayList();
        var_list.add(String.format("\"VARIABLE LABELS %s '%s'.\"", dataValue.get("cid"), getTitles(dataValue, null, null, false)));
        var_list.add(String.format("ADD VALUE LABELS %s", dataValue.get("cid")));
        List<JSONObject> items = (List<JSONObject>) dataValue.getOrDefault("items", Collections.emptyList());
        for (int i = 0; i < items.size(); i++) {
            JSONObject item = items.get(i);
            val_list.add(String.format("    %s '%s'%s", item.get("oid"), getUnquotedStr(item.getString("title"), true), i + 1 == items.size() ? "" : "."));
        }
        data.add(var_list);
        data.add(val_list);
        return data;
    }

    @Override
    public List<String> getSpssCodeV2(JSONObject param, QstructsDto qstruct) {
        List<String> head_list = new ArrayList<>();
        head_list.add(param.getString("cid"));
        List<JSONObject> items = (List<JSONObject>) param.getOrDefault("items", Collections.emptyList());
        head_list.addAll(items.stream().filter(item -> Objects.nonNull(item.getBoolean("is_open")) && item.getBoolean("is_open"))
                .map(item -> String.format("%s__%s__open", param.get("cid"), item.get("oid"))).collect(Collectors.toList()));
        if (ObjectUtil.isNotEmpty(qstruct.getScores()) && JSONObject.parseObject(qstruct.getScores()).containsKey(param.getString("gid"))) {
            head_list.add(getScoreRealcolV2(param));
        }
        return head_list;
    }

    @Override
    public String getQuestionTypeValue() {
        return QUESTION_TYPE_SINGLE.getValue();
    }
}